#include <Arduino.h>

// 74HC595引脚定义
#define PIN_DI 5   // 数据输入 (DS)
#define PIN_LAT 19 // 锁存时钟 (ST_CP)
#define PIN_CLK 18 // 移位时钟 (SH_CP)

byte dataRow;
byte dataCol;

// 心跳动画帧
const byte heart_beat[4][8] = {

    {0b00000000, // 心跳1
     0b01100110,
     0b11111111,
     0b11111111,
     0b01111110,
     0b00111100,
     0b00011000,
     0b00000000},

    {0b00000000, // 心跳2
     0b00000000,
     0b00100100,
     0b01111110,
     0b00111100,
     0b00011000,
     0b00000000,
     0b00000000},

};

int currentFrame = 0;
unsigned long previousMillis = 0;
const long interval = 300; // 动画帧间隔

void Display()
{
    shiftOut(PIN_DI, PIN_CLK, MSBFIRST, ~dataRow);
    shiftOut(PIN_DI, PIN_CLK, MSBFIRST, ~dataCol);
    digitalWrite(PIN_LAT, HIGH);
    digitalWrite(PIN_LAT, LOW);
}

void setup()
{
    Serial.begin(115200);

    pinMode(PIN_DI, OUTPUT);
    pinMode(PIN_LAT, OUTPUT);
    pinMode(PIN_CLK, OUTPUT);

    digitalWrite(PIN_LAT, LOW);
    digitalWrite(PIN_CLK, LOW);

    Serial.println("ESP32 8x8点阵屏心跳动画启动...");

    Serial.println("初始化完成！");
}

void loop()
{
    unsigned long currentMillis = millis();

    // 定时切换动画帧
    if (currentMillis - previousMillis >= interval)
    {
        previousMillis = currentMillis;

        // 心跳动画序列：0->1->2->3->2->1->0...
        if (currentFrame < 1)
        {
            currentFrame++;
        }
        else
        {
            currentFrame = 0;
        }
    }

    // 显示当前帧
    for (int row = 0; row < 8; row++)
    {
        dataRow = 1 << row;
        dataCol = ~heart_beat[currentFrame][row];
        Display();
        delay(1); // 短暂延迟确保显示稳定
    }
}